package com.yami.shop.service.impl;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.ShopWalletAmountType;
import com.yami.shop.bean.enums.ShopWalletChangeReason;
import com.yami.shop.bean.model.ShopWallet;
import com.yami.shop.bean.model.ShopWalletLog;
import com.yami.shop.bean.param.CustomerReqParam;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.i18n.LanguageEnum;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.PoiExcelUtil;
import com.yami.shop.dao.ShopWalletLogMapper;
import com.yami.shop.service.ShopWalletLogService;
import lombok.AllArgsConstructor;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 商家钱包记录
 *
 * @author Dwl
 * @date 2019-09-19 14:02:57
 */
@Service
@AllArgsConstructor
public class ShopWalletLogServiceImpl extends ServiceImpl<ShopWalletLogMapper, ShopWalletLog> implements ShopWalletLogService {

    private final ShopWalletLogMapper shopWalletLogMapper;


    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void saveShopWalletLog(ShopWallet oldShopWallet,ShopWallet newShopWallet , ShopWalletChangeReason shopWalletChangeReason, String orderNumber) {

        ShopWalletLog shopWalletLog = new ShopWalletLog();

        shopWalletLog.setCreateTime(new Date());

        shopWalletLog.setOrderNumber(orderNumber);
        shopWalletLog.setReason(shopWalletChangeReason.value());
        shopWalletLog.setShopId(oldShopWallet.getShopId());
        // 插入未结算金额修改记录
        if (!Objects.equals(oldShopWallet.getUnsettledAmount(), newShopWallet.getUnsettledAmount())) {
            double changeAmount = Arith.sub(oldShopWallet.getUnsettledAmount(), newShopWallet.getUnsettledAmount());
            shopWalletLog.setChangeAomunt(oldShopWallet.getUnsettledAmount() > newShopWallet.getUnsettledAmount() ? changeAmount: -changeAmount);
            shopWalletLog.setIoType(oldShopWallet.getUnsettledAmount() > newShopWallet.getUnsettledAmount() ? 0 : 1);
            shopWalletLog.setAmountType(ShopWalletAmountType.UNSETTLED_AMOUNT.value());
            shopWalletLogMapper.insert(shopWalletLog);
        }

        // 插入结算金额修改记录
        if (!Objects.equals(oldShopWallet.getSettledAmount(), newShopWallet.getSettledAmount())) {
            double changeAmount = Arith.sub(oldShopWallet.getSettledAmount(), newShopWallet.getSettledAmount());
            shopWalletLog.setChangeAomunt(oldShopWallet.getSettledAmount() > newShopWallet.getSettledAmount() ? changeAmount: -changeAmount);
            shopWalletLog.setIoType(oldShopWallet.getSettledAmount() > newShopWallet.getSettledAmount() ? 0 : 1);
            shopWalletLog.setAmountType(ShopWalletAmountType.SETTLED_AMOUNT.value());
            shopWalletLog.setWalletLogId(null);
            shopWalletLogMapper.insert(shopWalletLog);
        }

        // 插入冻结金额修改记录
        if (!Objects.equals(oldShopWallet.getFreezeAmount(), newShopWallet.getFreezeAmount())) {
            double changeAmount = Arith.sub(oldShopWallet.getFreezeAmount(), newShopWallet.getFreezeAmount());
            shopWalletLog.setChangeAomunt(oldShopWallet.getFreezeAmount() > newShopWallet.getFreezeAmount() ? changeAmount: -changeAmount);
            shopWalletLog.setIoType(oldShopWallet.getFreezeAmount() > newShopWallet.getFreezeAmount() ? 0 : 1);
            shopWalletLog.setAmountType(ShopWalletAmountType.FREEZE_AMOUNT.value());
            shopWalletLog.setWalletLogId(null);
            shopWalletLogMapper.insert(shopWalletLog);
        }

//        // 插入总结算金额记录
//        if (!Objects.equals(oldShopWallet.getTotalSettledAmount(), newShopWallet.getTotalSettledAmount())) {
//            double changeAmount = Arith.sub(oldShopWallet.getTotalSettledAmount(), newShopWallet.getTotalSettledAmount());
//            shopWalletLog.setChangeAomunt(oldShopWallet.getTotalSettledAmount() > newShopWallet.getTotalSettledAmount() ? changeAmount: -changeAmount);
//            shopWalletLog.setBeforeAmount(oldShopWallet.getTotalSettledAmount());
//            shopWalletLog.setAfterAmount(newShopWallet.getTotalSettledAmount());
//            shopWalletLog.setIoType(oldShopWallet.getTotalSettledAmount() > newShopWallet.getTotalSettledAmount() ? 0 : 1);
//            shopWalletLog.setAmountType(ShopWalletAmountType.TOTAL_SETTLED_AMOUNT.value());
//            shopWalletLogMapper.insert(shopWalletLog);
//        }
    }

    @Override
    public IPage<ShopWalletLog> pageByParam(PageParam<ShopWalletLog> page, ShopWalletLog shopWalletLog) {
        return shopWalletLogMapper.listByParam(page,shopWalletLog);
    }

    @Override
    public IPage<ShopWalletLog> pageAllShop(PageParam<ShopWallet> page, ShopWalletLog shopWalletLog) {
        return shopWalletLogMapper.pageAllByParam(page,shopWalletLog);
    }

    @Override
    public void excelShopWalletLog(CustomerReqParam customerReqParam, HttpServletResponse response) {
        List<ShopWalletLog> shopWalletLogs = shopWalletLogMapper.listShopWalletLogByParam(customerReqParam);
        boolean isCn = I18nMessage.getDbLang().equals(LanguageEnum.LANGUAGE_ZH_CN.getLang());
        ExcelWriter writer = ExcelUtil.getBigWriter();
        List<String> headerList;
        String[] headerCn = {"序号","店铺名称","金额类型","收支类型","改变金额","订单编号","退款编号","操作金额","平台补贴金额","商家补贴金额","分销金额","平台佣金","资金变化原因","创建时间"};
        String[] headerEn = {"Serial Number","Store Name", "Amount Type", "Type of income and expenses","Change Amount", "Order Number", "Refund Number", "Operation Amount", "Platform Subsidy Amount", "Merchant Subsidy Amount", "Distribution Amount", "Platform Commission", "Reason for Change of Funds", "Creation Time"};
        headerList = Arrays.asList(isCn ? headerCn : headerEn);
        writer.merge(headerList.size() - 1, I18nMessage.getMessage("yami.shop.wallet.log.excel"));
        writer.writeRow(headerList);
        Sheet sheet = writer.getSheet();
        for (int i = 1; i < headerList.size(); i++) {
            sheet.setColumnWidth(i, 20 * 256);
        }
        int row = 1;
        for (ShopWalletLog shopWalletLog : shopWalletLogs) {
            int firstRow = ++row;
            int col = -1;
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, row - 1);
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getShopName());
            ShopWalletAmountType amountType = ShopWalletAmountType.instance(shopWalletLog.getAmountType());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, isCn? amountType.getShopWalletAmountType() : amountType.getShopWalletAmountTypeEn());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getIoType().equals(1) ? I18nMessage.getMessage("yami.finance.income") : I18nMessage.getMessage("yami.finance.pay"));
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getChangeAomunt());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getOrderNumber());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getRefundSn());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getUserAmount());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getPlatformAmount());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getShopReduceAmount());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getDistributionAmount());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getPlatformCommission());
            ShopWalletChangeReason reason = ShopWalletChangeReason.instance(shopWalletLog.getReason());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, isCn ? reason.getShopWalletChangeReason() : reason.getShopWalletChangeReasonEn());
            PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, shopWalletLog.getCreateTime());
        }
        PoiExcelUtil.writeExcel(response, writer);
    }
}
